package guda.stark.biz.impl;

import guda.grape.autogen.common.page.BaseQuery;
import guda.grape.autogen.common.page.BizResult;
import guda.stark.biz.AdminBiz;
import guda.stark.biz.beans.vo.AdminVO;
import guda.stark.biz.beans.vo.AdminVillageVO;
import guda.stark.biz.constants.CommonResultCode;
import guda.stark.biz.form.AdminVillageForm;
import guda.stark.biz.form.LoginForm;
import guda.stark.biz.query.AdminQuery;
import guda.stark.biz.query.AdminVillageQuery;
import guda.stark.biz.query.RoleQuery;
import guda.stark.biz.query.VillageQuery;
import guda.stark.biz.util.ArrayUtil;
import guda.stark.biz.util.Md5Util;
import guda.stark.biz.util.Transform;
import guda.stark.biz.util.TransformHelper;
import guda.stark.dal.dao.AdminDAO;
import guda.stark.dal.dao.AdminVillageRelDAO;
import guda.stark.dal.dao.RoleDAO;
import guda.stark.dal.dao.VillageDAO;
import guda.stark.dal.dataobject.AdminDO;
import guda.stark.dal.dataobject.AdminVillageRelDO;
import guda.stark.dal.dataobject.RoleDO;
import guda.stark.dal.dataobject.VillageDO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.*;

public class AdminBizImpl implements AdminBiz {

    private final static Logger logger = LoggerFactory.getLogger(AdminBizImpl.class);

    @Autowired
    private AdminDAO adminDAO;
    @Autowired
    private RoleDAO roleDAO;
    @Autowired
    private VillageDAO villageDAO;
    @Autowired
    private AdminVillageRelDAO adminVillageRelDAO;
    @Autowired
    private TransactionTemplate transactionTemplate;

    public BizResult detail(long id) {
        BizResult bizResult = new BizResult();
        try {
            AdminDO adminDO = adminDAO.getAdminById(id);
            bizResult.data.put("adminDO", adminDO);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("query Admin error", e);
        }
        return bizResult;
    }

    public BizResult list(BaseQuery baseQuery) {
        BizResult bizResult = new BizResult();
        try {
            int totalCount = adminDAO.countForPage(baseQuery);
            baseQuery.setTotalCount(totalCount);
            List<AdminDO> adminList = adminDAO.selectForPage(baseQuery);
            RoleQuery roleQuery = new RoleQuery();
            roleQuery.setPageSize(100);
            List<RoleDO> roleDOs = roleDAO.selectForPage(roleQuery);
            Map<String, RoleDO> map = new HashMap<String, RoleDO>();
            for (RoleDO roleDO : roleDOs) {
                map.put(roleDO.getRoleName(), roleDO);
            }
            List<AdminVO> adminVOList = new ArrayList<AdminVO>(adminList.size());
            for (AdminDO adminDO : adminList) {
                AdminVO adminVO = new AdminVO();
                adminVO.setAdminDO(adminDO);
                String[] strings = ArrayUtil.string2Array(adminDO.getRoleName());
                List<RoleDO> roleDOList = new ArrayList<RoleDO>();
                if (strings != null) {
                    for (String s : strings) {
                        roleDOList.add(map.get(s));
                    }
                }
                adminVO.setRoleDOList(roleDOList);
                adminVOList.add(adminVO);
            }
            bizResult.data.put("adminVOList", adminVOList);
            bizResult.data.put("query", baseQuery);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("view Admin list error", e);
        }
        return bizResult;
    }

    public BizResult delete(long id) {
        BizResult bizResult = new BizResult();
        try {
            adminDAO.delAdminById(id);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("delete admin error", e);
        }
        return bizResult;
    }

    public BizResult create(AdminDO adminDO) {
        BizResult bizResult = new BizResult();
        try {
            //判断是否重名
            AdminQuery adminQuery = new AdminQuery();
            adminQuery.setLoginName(adminDO.getLoginName());
            int i = adminDAO.countForPage(adminQuery);
            if (i > 0) {
                bizResult.code = CommonResultCode.NAME_REPEAT;
                return bizResult;
            }
            long id = adminDAO.insert(adminDO);
            bizResult.data.put("id", id);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("create Admin error", e);
        }
        return bizResult;
    }

    @Override
    public BizResult update(AdminDO adminDO) {
        BizResult bizResult = new BizResult();
        try {
            //判断是否重名
            AdminQuery adminQuery = new AdminQuery();
            adminQuery.setLoginName(adminDO.getLoginName());
            List<AdminDO> adminDOs = adminDAO.selectForPage(adminQuery);
            if (adminDOs.size() > 1) {
                bizResult.code = CommonResultCode.NAME_REPEAT;
                return bizResult;
            } else if (adminDOs.size() == 1) {
                if (adminDOs.get(0).getAdminId().longValue() != adminDO.getAdminId().longValue()) {
                    bizResult.code = CommonResultCode.NAME_REPEAT;
                    return bizResult;
                }
            }
            adminDAO.updateByIdSelective(adminDO);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("update Admin error", e);
        }
        return bizResult;
    }

    @Override
    public BizResult login(LoginForm loginForm) {
        BizResult bizResult = new BizResult();
        AdminDO adminDO = adminDAO.selectByUser(loginForm.getUsername(), Md5Util.md5(loginForm.getPassword()));
        if (adminDO == null) {
            return bizResult;
        }
        bizResult.data.put("admin", adminDO);
        bizResult.success = true;
        return bizResult;
    }

    @Override
    public BizResult queryForCreate() {
        BizResult bizResult = new BizResult();
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setPageSize(100);
        List<RoleDO> roleDOs = roleDAO.selectForPage(roleQuery);
        bizResult.data.put("roleList", roleDOs);
        bizResult.success = true;
        return bizResult;
    }

    @Override
    public BizResult queryForEdit(long id) {
        BizResult bizResult = new BizResult();
        try {
            AdminDO adminDO = adminDAO.getAdminById(id);
            bizResult.data.put("adminDO", adminDO);
            RoleQuery roleQuery = new RoleQuery();
            roleQuery.setPageSize(100);
            List<RoleDO> roleDOs = roleDAO.selectForPage(roleQuery);
            bizResult.data.put("roleList", roleDOs);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("query Admin error", e);
        }
        return bizResult;
    }

    @Override
    public BizResult queryAllVillage(long id) {
        BizResult bizResult = new BizResult();
        AdminVillageQuery adminVillageQuery = new AdminVillageQuery();
        adminVillageQuery.setAdminId(id);
        adminVillageQuery.setPageSize(500);
        List<AdminVillageRelDO> adminVillageRelDOs = adminVillageRelDAO.selectForPage(adminVillageQuery);
        Set<Long> villageIdSet = TransformHelper.transform2Set(adminVillageRelDOs, new Transform<AdminVillageRelDO, Long>() {
            @Override
            public Long transform(AdminVillageRelDO object) {
                return object.getVillageId();
            }
        });
        VillageQuery villageQuery = new VillageQuery();
        villageQuery.setPageSize(500);
        List<VillageDO> villageDOs = villageDAO.selectForPage(villageQuery);
        List<AdminVillageVO> adminVillageVOList = new ArrayList<AdminVillageVO>(villageDOs.size());
        for (VillageDO villageDO : villageDOs) {
            AdminVillageVO adminVillageVO = new AdminVillageVO();
            adminVillageVO.setVillageDO(villageDO);
            if (villageIdSet.contains(villageDO.getVillageId())) {
                adminVillageVO.setBinded(true);
            }
            adminVillageVOList.add(adminVillageVO);
        }
        bizResult.data.put("adminVillageVOList", adminVillageVOList);
        bizResult.success = true;
        return bizResult;
    }

    @Override
    public BizResult bindVillage(final AdminVillageForm adminVillageForm) {
        BizResult bizResult = new BizResult();
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                for (Long villageId : adminVillageForm.getVillageIdList()) {

                    AdminVillageRelDO adminVillageRel = adminVillageRelDAO.getAdminVillageRel(adminVillageForm.getAdminId(), villageId);
                    if (adminVillageRel == null) {
                        adminVillageRel = new AdminVillageRelDO();
                        adminVillageRel.setVillageId(villageId);
                        adminVillageRel.setAdminId(adminVillageForm.getAdminId());
                        adminVillageRelDAO.insert(adminVillageRel);
                    }
                }
            }
        });

        bizResult.success = true;
        return bizResult;
    }


}
